Plotar nossos dados é uma das melhores maneiras de explorá-los rapidamente e também ver as várias relações entre variáveis.

xistem três sistemas de plotagem principais no R, o base plotting system, o pacote lattice, and o pacote ggplot2.

Hoje vamos aprender sobre o pacote ggplot2, porque é o mais eficaz para a criação de gráficos de qualidade de publicação.

ggplot2 é construído sobre a gramática de gráficos, a ideia de que qualquer gráfico pode ser expresso a partir do mesmo conjunto de componentes: um conjunto de dados, um sistema de coordenadas e um conjunto de geoms - a representação visual dos conjunto de pontos.

A chave para entender ggplot2 é pensar em uma figura em camadas. Essa ideia pode ser familiar para você se você usou programas de edição de imagem como Photoshop, Illustrator ou Inkscape.

Vamos começar com um exemplo:

library("ggplot2")
ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) +
  geom_point()

Então a primeira coisa que fazemos é chamar a função ggplot. Esta função permite que R saiba que estamos criando um novo gráfico e que qualquer dos argumentos que damos à função ggplot são as opções globais para este gráfico: elas se aplicam a todas as camadas do gráfico.

Passamos em dois argumentos para ggplot. Primeiro, dizemos ao ggplot quais dados queremos mostrar na nossa figura, neste exemplo os dados gapminder que lemos anteriormente. Para o segundo argumento passamos na função aes, que diz ao ggplot como variáveis nos dados delineiam as propriedades aesthetic da figura, neste caso as localizações de x e y. Aqui nós dissemos ao ggplot que queremos graficar a coluna “gdpPercap” do data frame gapminder no eixo x, e a coluna “lifeExp” no eixo y. Observe que não precisamos explicitamente passar essas colunas (por exemplo x = gapminder[, "gdpPercap"]), isso ocorre porque o ggplot é inteligente o suficiente para saber olhar os dados dessa coluna!

Por si só, a chamada para ggplot não é suficiente para desenhar uma figura:

ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp))

Precisamos dizer ao ggplot como queremos representar visualmente os dados, o que fazemos adicionando uma nova camada geom. No nosso exemplo, usamos geom_point, que diz ao ggplot que queremos representar visualmente a relação entre x e y como um scatterplot dos pontos:

ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) +
  geom_point()

Challenge 1

Modifique o exemplo para que a figura visualize como a expectativa de vida mudou ao longo do tempo:

ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) + geom_point()

Dica: o conjunto de dados gapminder tem uma coluna chamada “year”, que deve aparecer no eixo x.

Solution to challenge 1

Here is one possible solution:

ggplot(data = gapminder, aes(x = year, y = lifeExp)) + geom_point()

{: .solution} {: .challenge}

Challenge 2

In the previous examples and challenge we’ve used the aes function to tell the scatterplot geom about the x and y locations of each point. Another aesthetic property we can modify is the point color. Modify the code from the previous challenge to color the points by the “continent” column. What trends do you see in the data? Are they what you expected?

Solution to challenge 2

In the previous examples and challenge we’ve used the aes function to tell the scatterplot geom about the x and y locations of each point. Another aesthetic property we can modify is the point color. Modify the code from the previous challenge to color the points by the “continent” column. What trends do you see in the data? Are they what you expected?

ggplot(data = gapminder, aes(x = year, y = lifeExp, color=continent)) +
  geom_point()

{: .solution} {: .challenge}

Layers

Using a scatterplot probably isn’t the best for visualizing change over time. Instead, let’s tell ggplot to visualize the data as a line plot:

ggplot(data = gapminder, aes(x=year, y=lifeExp, by=country, color=continent)) +
  geom_line()

Instead of adding a geom_point layer, we’ve added a geom_line layer. We’ve added the by aesthetic, which tells ggplot to draw a line for each country.

But what if we want to visualize both lines and points on the plot? We can simply add another layer to the plot:

ggplot(data = gapminder, aes(x=year, y=lifeExp, by=country, color=continent)) +
  geom_line() + geom_point()

It’s important to note that each layer is drawn on top of the previous layer. In this example, the points have been drawn on top of the lines. Here’s a demonstration:

ggplot(data = gapminder, aes(x=year, y=lifeExp, by=country)) +
  geom_line(aes(color=continent)) + geom_point()

In this example, the aesthetic mapping of color has been moved from the global plot options in ggplot to the geom_line layer so it no longer applies to the points. Now we can clearly see that the points are drawn on top of the lines.

Tip: Setting an aesthetic to a value instead of a mapping

So far, we’ve seen how to use an aesthetic (such as color) as a mapping to a variable in the data. For example, when we use geom_line(aes(color=continent)), ggplot will give a different color to each continent. But what if we want to change the colour of all lines to blue? You may think that geom_line(aes(color="blue")) should work, but it doesn’t. Since we don’t want to create a mapping to a specific variable, we simply move the color specification outside of the aes() function, like this: geom_line(color="blue"). {: .callout}

Challenge 3

Switch the order of the point and line layers from the previous example. What happened?

Solution to challenge 3

Switch the order of the point and line layers from the previous example. What happened?

ggplot(data = gapminder, aes(x=year, y=lifeExp, by=country)) +
 geom_point() + geom_line(aes(color=continent))

The lines now get drawn over the points!

{: .solution} {: .challenge}

Transformations and statistics

Ggplot also makes it easy to overlay statistical models over the data. To demonstrate we’ll go back to our first example:

ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp, color=continent)) +
  geom_point()

Currently it’s hard to see the relationship between the points due to some strong outliers in GDP per capita. We can change the scale of units on the x axis using the scale functions. These control the mapping between the data values and visual values of an aesthetic. We can also modify the transparency of the points, using the alpha function, which is especially helpful when you have a large amount of data which is very clustered.

ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) +
  geom_point(alpha = 0.5) + scale_x_log10()

The log10 function applied a transformation to the values of the gdpPercap column before rendering them on the plot, so that each multiple of 10 now only corresponds to an increase in 1 on the transformed scale, e.g. a GDP per capita of 1,000 is now 3 on the y axis, a value of 10,000 corresponds to 4 on the y axis and so on. This makes it easier to visualize the spread of data on the x-axis.

Tip Reminder: Setting an aesthetic to a value instead of a mapping

Notice that we used geom_point(alpha = 0.5). As the previous tip mentioned, using a setting outside of the aes() function will cause this value to be used for all points, which is what we want in this case. But just like any other aesthetic setting, alpha can also be mapped to a variable in the data. For example, we can give a different transparency to each continent with geom_point(aes(alpha = continent)). {: .callout}

We can fit a simple relationship to the data by adding another layer, geom_smooth:

ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) +
  geom_point() + scale_x_log10() + geom_smooth(method="lm")

We can make the line thicker by setting the size aesthetic in the geom_smooth layer:

ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) +
  geom_point() + scale_x_log10() + geom_smooth(method="lm", size=1.5)

There are two ways an aesthetic can be specified. Here we set the size aesthetic by passing it as an argument to geom_smooth. Previously in the lesson we’ve used the aes function to define a mapping between data variables and their visual representation.

Challenge 4a

Modify the color and size of the points on the point layer in the previous example.

Hint: do not use the aes function.

Solution to challenge 4a

Modify the color and size of the points on the point layer in the previous example.

Hint: do not use the aes function.

ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) +
 geom_point(size=3, color="orange") + scale_x_log10() +
 geom_smooth(method="lm", size=1.5)

{: .solution} {: .challenge}

Challenge 4b

Modify your solution to Challenge 4a so that the points are now a different shape and are colored by continent with new trendlines. Hint: The color argument can be used inside the aesthetic.

Solution to challenge 4b

Modify Challenge 4 so that the points are now a different shape and are colored by continent with new trendlines.

Hint: The color argument can be used inside the aesthetic.

ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp, color = continent)) +
geom_point(size=3, shape=17) + scale_x_log10() +
geom_smooth(method="lm", size=1.5)

{: .solution} {: .challenge}

Multi-panel figures

Earlier we visualized the change in life expectancy over time across all countries in one plot. Alternatively, we can split this out over multiple panels by adding a layer of facet panels. Focusing only on those countries with names that start with the letter “A” or “Z”.

Tip

We start by subsetting the data. We use the substr function to pull out a part of a character string; in this case, the letters that occur in positions start through stop, inclusive, of the gapminder$country vector. The operator %in% allows us to make multiple comparisons rather than write out long subsetting conditions (in this case, starts.with %in% c("A", "Z") is equivalent to starts.with == "A" | starts.with == "Z") {: .callout}

starts.with <- substr(gapminder$country, start = 1, stop = 1)
az.countries <- gapminder[starts.with %in% c("A", "Z"), ]
ggplot(data = az.countries, aes(x = year, y = lifeExp, color=continent)) +
  geom_line() + facet_wrap( ~ country)

The facet_wrap layer took a “formula” as its argument, denoted by the tilde (~). This tells R to draw a panel for each unique value in the country column of the gapminder dataset.

Modifying text

To clean this figure up for a publication we need to change some of the text elements. The x-axis is too cluttered, and the y axis should read “Life expectancy”, rather than the column name in the data frame.

We can do this by adding a couple of different layers. The theme layer controls the axis text, and overall text size, and there are special layers for changing the axis labels. To change the legend title, we need to use the scales layer.

ggplot(data = az.countries, aes(x = year, y = lifeExp, color=continent)) +
  geom_line() + facet_wrap( ~ country) +
  xlab("Year") + ylab("Life expectancy") + ggtitle("Figure 1") +
  scale_colour_discrete(name="Continent") +
  theme(axis.text.x=element_blank(), axis.ticks.x=element_blank())

This is a taste of what you can do with ggplot2. RStudio provides a really useful cheat sheet of the different layers available, and more extensive documentation is available on the ggplot2 website. Finally, if you have no idea how to change something, a quick Google search will usually send you to a relevant question and answer on Stack Overflow with reusable code to modify!

Challenge 5

Create a density plot of GDP per capita, filled by continent.

Advanced: - Transform the x axis to better visualise the data spread. - Add a facet layer to panel the density plots by year.

Solution to challenge 5

Create a density plot of GDP per capita, filled by continent.

Advanced: - Transform the x axis to better visualise the data spread. - Add a facet layer to panel the density plots by year.

ggplot(data = gapminder, aes(x = gdpPercap, fill=continent)) +
 geom_density(alpha=0.6) + facet_wrap( ~ year) + scale_x_log10()

{: .solution} {: .challenge}